from torch import nn
import torch
# functional 是pytorch的函数
"""
# 激活函数：如 F.relu()、F.sigmoid()、F.tanh()，用于引入非线性。
# 损失函数：如 F.cross_entropy()（分类任务）、F.mse_loss()（回归任务）。
# 卷积/池化操作：如 F.conv2d()（自定义卷积核）、F.max_pool2d()（最大池化）。
# 归一化与正则化：如 F.batch_norm()（批归一化）、F.dropout()（随机失活）。
# 张量操作：如 F.interpolate()（上采样）、F.pad()（填充）。
"""
import torch.nn.functional as F
import numpy as np

# 条带池化模块
class StripPooling(nn.Module):
    """
    条带池化模块(CVPR2020)

    通过水平和垂直条带池化捕获长距离空间上下文信息，解决传统方形池化对长条形目标建模不足的问题
    核心优势：
    1. 长条形池化核（1xN/Nx1）可捕获离散区域的远程关系
    2. 窄核形状保持局部细节捕捉能力
    论文链接：https://arxiv.org/abs/2003.13328
    """

    def __init__(self, in_channels, up_kwargs={'mode': 'bilinear', 'align_corners': True}):
        super(StripPooling, self).__init__()
        # 水平条带池化(1xW) - 捕获宽度方向的全局上下文
        self.pool1 = nn.AdaptiveAvgPool2d((1, None))
        # 垂直条带池化(Hx1) - 捕获高度方向的全局上下文
        self.pool2 = nn.AdaptiveAvgPool2d((None, 1))

        # 中间层通道数压缩为输入通道的1/4（平衡计算量和特征表达能力）
        inter_channels = int(in_channels / 4)

        # 特征压缩层：1x1卷积+BN+ReLU
        self.conv1 = nn.Sequential(
            nn.Conv2d(in_channels, inter_channels, 1, bias=False),  # 通道压缩
            nn.BatchNorm2d(inter_channels),  # 批归一化
            nn.ReLU(True)  # 激活函数
        )

        # 水平特征处理路径：1x3卷积+BN（处理水平条带特征）
        self.conv2 = nn.Sequential(
            nn.Conv2d(inter_channels, inter_channels, (1, 3), 1, (0, 1), bias=False),
            nn.BatchNorm2d(inter_channels)
        )

        # 垂直特征处理路径：3x1卷积+BN（处理垂直条带特征）
        self.conv3 = nn.Sequential(
            nn.Conv2d(inter_channels, inter_channels, (3, 1), 1, (1, 0), bias=False),
            nn.BatchNorm2d(inter_channels)
        )

        # 特征融合层：3x3卷积+BN+ReLU（融合双路径特征）
        self.conv4 = nn.Sequential(
            nn.Conv2d(inter_channels, inter_channels, 3, 1, 1, bias=False),
            nn.BatchNorm2d(inter_channels),
            nn.ReLU(True)
        )

        # 输出层：1x1卷积+BN（恢复原始通道数）
        self.conv5 = nn.Sequential(
            nn.Conv2d(inter_channels, in_channels, 1, bias=False),
            nn.BatchNorm2d(in_channels)
        )

        # 上采样参数配置（双线性插值+对齐角点）
        self._up_kwargs = up_kwargs

    def forward(self, x):
        # 获取输入特征图尺寸[B,C,H,W]
        _, _, h, w = x.size()

        # 特征压缩（降低计算量）
        x1 = self.conv1(x)

        # 水平路径处理（1xW全局上下文建模）
        x2 = F.interpolate(
            self.conv2(self.pool1(x1)),  # 水平池化+特征转换
            (h, w),  # 上采样到原尺寸
            **self._up_kwargs
        )

        # 垂直路径处理（Hx1全局上下文建模）
        x3 = F.interpolate(
            self.conv3(self.pool2(x1)),  # 垂直池化+特征转换
            (h, w),  # 上采样到原尺寸
            **self._up_kwargs
        )

        # 双路径特征融合（元素相加+非线性激活）
        x4 = self.conv4(F.relu_(x2 + x3))

        # 输出特征生成（通道恢复）
        out = self.conv5(x4)

        # 残差连接（保留原始特征）+ ReLU激活
        return F.relu_(x + out)

#  残差膨胀卷积块
class REBNCONV(nn.Module):
    """
    残差膨胀卷积块(Residual Expanded Bottleneck Convolution)

    核心特点：
    1. 采用深度可分离卷积结构降低计算量[5,7](@ref)
    2. 膨胀卷积(dilated conv)扩大感受野[3](@ref)
    3. 参数化ReLU(PReLU)增强非线性表达能力[8,9](@ref)
    典型应用于U-Net类分割网络[1,4](@ref)
    """

    def __init__(self, in_ch=4, out_ch=4, dirate=1):
        super(REBNCONV, self).__init__()

        # 深度可分离卷积的深度卷积部分
        # groups=in_ch实现通道独立卷积[5,7](@ref)
        self.conv_s1 = nn.Conv2d(
            in_ch, in_ch, 3,
            padding=1 * dirate,  # 动态调整的膨胀填充
            dilation=1 * dirate,  # 膨胀率控制感受野大小[3](@ref)
            groups=in_ch  # 深度可分离卷积关键参数[6](@ref)
        )

        # 逐点卷积部分(1x1卷积进行通道变换)
        self.conv_s2 = nn.Conv2d(
            in_ch, out_ch, 1  # 1x1卷积整合通道信息[7](@ref)
        )

        # 批归一化层(加速训练收敛)
        self.bn_s1 = nn.BatchNorm2d(out_ch)

        # 参数化ReLU激活(可学习负区间斜率)[8,9](@ref)
        self.relu_s1 = nn.PReLU()  # 默认alpha=0.25

    def forward(self, x):
        """
        前向传播流程：
        1. 深度卷积(空间特征提取)
        2. 逐点卷积(通道信息整合)
        3. 批归一化(稳定数值分布)
        4. 参数化ReLU(非线性激活)
        """
        xout = self.relu_s1(
            self.bn_s1(
                self.conv_s2(
                    self.conv_s1(x)  # 深度卷积
                )  # 逐点卷积
            )  # 批归一化
        )  # 参数化激活
        return xout

## upsample tensor 'src' to have the same spatial size with tensor 'tar' 翻译 ：将src张量resize成tar张量的尺寸
def _upsample_like(src, tar):
    """
    将源张量上采样至目标张量的空间尺寸（保持通道数不变）

    核心功能：实现动态尺寸适应的双线性插值上采样

    参数说明：
        src (Tensor): 待上采样的4D输入张量，形状为[B, C, H_src, W_src]
        tar (Tensor): 目标尺寸参考张量，取其H/W维度作为目标尺寸

    技术细节：
        1. 采用双线性插值(bilinear)算法，在速度与质量间取得平衡
        2. align_corners=True确保角像素精确对齐，避免边缘模糊
        3. 频谱特性：上采样会压缩信号频谱，可能引入镜像分量[1](@ref)

    数学原理：
        输出像素值通过加权邻域像素计算：
        $$P_{out_big} = \sum_{i=1}^4 w_i \cdot P_i$$
        其中权重$w_i$由双线性核函数确定

    典型应用场景：
        - U-Net等分割网络的解码器层
        - 特征金字塔(FPN)的多尺度融合
        - 超分辨率重建的前处理

    注意事项：
        1. 推荐使用F.interpolate替代旧版F.upsample[6,7](@ref)
        2. 大比例上采样建议配合转置卷积使用
        3. 对齐模式(align_corners)影响几何形变精度[7](@ref)
    """
    src = F.interpolate(
        src,
        size=tar.shape[2:],  # 仅匹配H/W维度
        mode='bilinear',  # 最优插值算法选择[7](@ref)
        align_corners=True  # 保持角点对齐
    )
    return src

# 7层残差U型块
class RSU7(nn.Module):
    """7层残差U型块(Residual U-block)
    核心特点：
    1. 编码器-解码器结构：7层下采样+6层上采样
    2. 膨胀卷积(dirate)扩大感受野
    3. 跳跃连接保留底层特征
    典型应用于图像分割任务（如U²-Net）
    """
    def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
        super(RSU7, self).__init__()
        # 输入特征转换
        self.rebnconvin = REBNCONV(in_ch, out_ch, dirate=1)

        # 编码器部分（下采样）
        self.rebnconv1 = REBNCONV(out_ch, mid_ch, dirate=1)
        self.pool1 = nn.MaxPool2d(2, stride=2, ceil_mode=True)  # 尺寸减半

        self.rebnconv2 = REBNCONV(mid_ch, mid_ch, dirate=1)
        self.pool2 = nn.MaxPool2d(2, stride=2, ceil_mode=True)

        self.rebnconv3 = REBNCONV(mid_ch, mid_ch, dirate=1)
        self.pool3 = nn.MaxPool2d(2, stride=2, ceil_mode=True)

        self.rebnconv4 = REBNCONV(mid_ch, mid_ch, dirate=1)
        self.pool4 = nn.MaxPool2d(2, stride=2, ceil_mode=True)

        self.rebnconv5 = REBNCONV(mid_ch, mid_ch, dirate=1)
        self.pool5 = nn.MaxPool2d(2, stride=2, ceil_mode=True)

        # 瓶颈层（最大感受野）
        self.rebnconv6 = REBNCONV(mid_ch, mid_ch, dirate=1)
        self.rebnconv7 = REBNCONV(mid_ch, mid_ch, dirate=2)  # 膨胀卷积扩大感受野

        # 解码器部分（上采样）
        self.rebnconv6d = REBNCONV(mid_ch*2, mid_ch, dirate=1)  # 特征融合
        self.rebnconv5d = REBNCONV(mid_ch*2, mid_ch, dirate=1)
        self.rebnconv4d = REBNCONV(mid_ch*2, mid_ch, dirate=1)
        self.rebnconv3d = REBNCONV(mid_ch*2, mid_ch, dirate=1)
        self.rebnconv2d = REBNCONV(mid_ch*2, mid_ch, dirate=1)
        self.rebnconv1d = REBNCONV(mid_ch*2, out_ch, dirate=1)  # 恢复原始通道数

    def forward(self, x):
        """前向传播流程：
        1. 编码器逐层下采样提取特征
        2. 瓶颈层捕获全局上下文
        3. 解码器逐层上采样恢复分辨率
        4. 跳跃连接融合不同尺度特征
        """
        hx = x
        hxin = self.rebnconvin(hx)  # 初始特征转换

        # 编码器路径
        hx1 = self.rebnconv1(hxin)
        hx = self.pool1(hx1)

        hx2 = self.rebnconv2(hx)
        hx = self.pool2(hx2)

        hx3 = self.rebnconv3(hx)
        hx = self.pool3(hx3)

        hx4 = self.rebnconv4(hx)
        hx = self.pool4(hx4)

        hx5 = self.rebnconv5(hx)
        hx = self.pool5(hx5)

        hx6 = self.rebnconv6(hx)
        hx7 = self.rebnconv7(hx6)  # 最大感受野层

        # 解码器路径（含跳跃连接）
        hx6d = self.rebnconv6d(torch.cat((hx7, hx6), 1))
        hx6dup = _upsample_like(hx6d, hx5)

        hx5d = self.rebnconv5d(torch.cat((hx6dup, hx5), 1))
        hx5dup = _upsample_like(hx5d, hx4)

        hx4d = self.rebnconv4d(torch.cat((hx5dup, hx4), 1))
        hx4dup = _upsample_like(hx4d, hx3)

        hx3d = self.rebnconv3d(torch.cat((hx4dup, hx3), 1))
        hx3dup = _upsample_like(hx3d, hx2)

        hx2d = self.rebnconv2d(torch.cat((hx3dup, hx2), 1))
        hx2dup = _upsample_like(hx2d, hx1)

        hx1d = self.rebnconv1d(torch.cat((hx2dup, hx1), 1))

        return hx1d + hxin  # 残差连接增强梯度流动
class RSU6(nn.Module):#UNet06DRES(nn.Module):
    """6层残差U型块(Residual U-block)
    核心特点：
    1. 编码器-解码器结构：6层下采样+5层上采样
    2. 膨胀卷积(dirate)扩大感受野
    3. 跳跃连接保留底层特征
    典型应用于图像分割任务（如U²-Net）
    """
    def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
        super(RSU6,self).__init__()

        self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)

        self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
        self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1)
        self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1)
        self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1)
        self.pool4 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=1)

        self.rebnconv6 = REBNCONV(mid_ch,mid_ch,dirate=2)

        self.rebnconv5d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)

    def forward(self,x):

        hx = x

        hxin = self.rebnconvin(hx)

        hx1 = self.rebnconv1(hxin)
        hx = self.pool1(hx1)

        hx2 = self.rebnconv2(hx)
        hx = self.pool2(hx2)

        hx3 = self.rebnconv3(hx)
        hx = self.pool3(hx3)

        hx4 = self.rebnconv4(hx)
        hx = self.pool4(hx4)

        hx5 = self.rebnconv5(hx)

        hx6 = self.rebnconv6(hx5)


        hx5d =  self.rebnconv5d(torch.cat((hx6,hx5),1))
        hx5dup = _upsample_like(hx5d,hx4)

        hx4d = self.rebnconv4d(torch.cat((hx5dup,hx4),1))
        hx4dup = _upsample_like(hx4d,hx3)

        hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1))
        hx3dup = _upsample_like(hx3d,hx2)

        hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1))
        hx2dup = _upsample_like(hx2d,hx1)

        hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1))

        return hx1d + hxin
class RSU5(nn.Module):#UNet05DRES(nn.Module):
    """5层残差U型块(Residual U-block)
    核心特点：
    1. 编码器-解码器结构：5层下采样+4层上采样
    2. 膨胀卷积(dirate)扩大感受野
    3. 跳跃连接保留底层特征
    典型应用于图像分割任务（如U²-Net）
    """

    def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
        super(RSU5,self).__init__()

        self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)

        self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
        self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1)
        self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1)
        self.pool3 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=1)

        self.rebnconv5 = REBNCONV(mid_ch,mid_ch,dirate=2)

        self.rebnconv4d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)

    def forward(self,x):

        hx = x

        hxin = self.rebnconvin(hx)

        hx1 = self.rebnconv1(hxin)
        hx = self.pool1(hx1)

        hx2 = self.rebnconv2(hx)
        hx = self.pool2(hx2)

        hx3 = self.rebnconv3(hx)
        hx = self.pool3(hx3)

        hx4 = self.rebnconv4(hx)

        hx5 = self.rebnconv5(hx4)

        hx4d = self.rebnconv4d(torch.cat((hx5,hx4),1))
        hx4dup = _upsample_like(hx4d,hx3)

        hx3d = self.rebnconv3d(torch.cat((hx4dup,hx3),1))
        hx3dup = _upsample_like(hx3d,hx2)

        hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1))
        hx2dup = _upsample_like(hx2d,hx1)

        hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1))

        return hx1d + hxin
class RSU4(nn.Module):#UNet04DRES(nn.Module):
    """4层残差U型块(Residual U-block)
    核心特点：
    1. 编码器-解码器结构：4层下采样+3层上采样
    2. 膨胀卷积(dirate)扩大感受野
    3. 跳跃连接保留底层特征
    典型应用于图像分割任务（如U²-Net）
    """

    def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
        super(RSU4,self).__init__()

        self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)

        self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
        self.pool1 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=1)
        self.pool2 = nn.MaxPool2d(2,stride=2,ceil_mode=True)

        self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=1)

        self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=2)

        self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=1)
        self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)

    def forward(self,x):

        hx = x

        hxin = self.rebnconvin(hx)

        hx1 = self.rebnconv1(hxin)
        hx = self.pool1(hx1)

        hx2 = self.rebnconv2(hx)
        hx = self.pool2(hx2)

        hx3 = self.rebnconv3(hx)

        hx4 = self.rebnconv4(hx3)

        hx3d = self.rebnconv3d(torch.cat((hx4,hx3),1))
        hx3dup = _upsample_like(hx3d,hx2)

        hx2d = self.rebnconv2d(torch.cat((hx3dup,hx2),1))
        hx2dup = _upsample_like(hx2d,hx1)

        hx1d = self.rebnconv1d(torch.cat((hx2dup,hx1),1))

        return hx1d + hxin
class RSU4F(nn.Module):#UNet04FRES(nn.Module):
    """4层残差U型块(Residual U-block)
    核心特点：
    1. 编码器-解码器结构：4层下采样+3层上采样
    2. 膨胀卷积(dirate)扩大感受野
    3. 跳跃连接保留底层特征
    4. 输出特征图与输入特征图尺寸相同
    典型应用于图像分割任务（如U²-Net）
    """

    def __init__(self, in_ch=3, mid_ch=12, out_ch=3):
        super(RSU4F,self).__init__()

        self.rebnconvin = REBNCONV(in_ch,out_ch,dirate=1)

        self.rebnconv1 = REBNCONV(out_ch,mid_ch,dirate=1)
        self.rebnconv2 = REBNCONV(mid_ch,mid_ch,dirate=2)
        self.rebnconv3 = REBNCONV(mid_ch,mid_ch,dirate=4)

        self.rebnconv4 = REBNCONV(mid_ch,mid_ch,dirate=8)

        self.rebnconv3d = REBNCONV(mid_ch*2,mid_ch,dirate=4)
        self.rebnconv2d = REBNCONV(mid_ch*2,mid_ch,dirate=2)
        self.rebnconv1d = REBNCONV(mid_ch*2,out_ch,dirate=1)

    def forward(self,x):

        hx = x

        hxin = self.rebnconvin(hx)

        hx1 = self.rebnconv1(hxin)
        hx2 = self.rebnconv2(hx1)
        hx3 = self.rebnconv3(hx2)

        hx4 = self.rebnconv4(hx3)

        hx3d = self.rebnconv3d(torch.cat((hx4,hx3),1))
        hx2d = self.rebnconv2d(torch.cat((hx3d,hx2),1))
        hx1d = self.rebnconv1d(torch.cat((hx2d,hx1),1))

        return hx1d + hxin

# 定义一个3x3卷积层，保持特征图尺寸不变（padding=1）
def Conv3X3(in_, out):
    return torch.nn.Conv2d(in_, out, 3, padding=1)

# 基础卷积+ReLU模块
class ConvRelu(nn.Module):
    """基础卷积+ReLU模块"""
    def __init__(self, in_, out):
        super().__init__()
        self.conv = Conv3X3(in_, out)  # 3x3卷积
        self.activation = torch.nn.ReLU(inplace=True)  # 原地ReLU激活节省内存

    def forward(self, x):
        x = self.conv(x)
        x = self.activation(x)
        return x

# 下采样模块
class Down(nn.Module):
    """下采样模块"""
    def __init__(self, nn):
        super(Down,self).__init__()
        self.nn = nn  # 内部神经网络模块（如RSU模块）
        # 最大池化层，保留最大值位置索引供后续上采样使用
        self.maxpool_with_argmax = torch.nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True)

    def forward(self,inputs):
        down = self.nn(inputs)  # 通过神经网络
        unpooled_shape = down.size()  # 记录下采样前尺寸
        outputs, indices = self.maxpool_with_argmax(down)  # 2倍下采样
        return outputs, down  # 返回池化结果和池化前特征

# 上采样模块
class Up(nn.Module):
    """上采样模块"""
    def __init__(self, nn):
        super().__init__()
        self.nn = nn  # 内部神经网络模块

    def forward(self,inputs,dest):
        outputs = _upsample_like(inputs,dest)  # 将输入上采样到目标尺寸
        outputs = self.nn(outputs)  # 通过神经网络
        return outputs

# 特征融合模块
class Fuse(nn.Module):
    """特征融合模块"""
    def __init__(self, nn, scale):
        super().__init__()
        self.nn = nn  # 内部神经网络模块
        self.scale = scale  # 上采样比例因子
        self.conv = Conv3X3(64,1)  # 最终1x1卷积输出预测

    def forward(self,down_inp,up_inp):
        outputs = torch.cat([down_inp, up_inp], 1)  # 通道维度拼接特征
        # 双线性插值上采样到指定尺度
        outputs = F.interpolate(outputs, scale_factor=self.scale, mode='bilinear', align_corners=True)
        outputs = self.nn(outputs)  # 通过神经网络
        return self.conv(outputs)  # 输出预测

# DeepCrack网络主架构（U-Net结构+多尺度特征融合）
class DeepCrack_uu_Sp_3(nn.Module):
    """
    DeepCrack网络主架构（U-Net结构+多尺度特征融合）
    """
    def __init__(self, num_classes=1000):
        super(DeepCrack_uu_Sp_3, self).__init__()

        # 编码器部分（5级下采样）
        self.down1 = Down(torch.nn.Sequential(
            RSU7(3,16,64),  # 7层RSU模块，输入3通道输出64通道
        ))
        self.down2 = Down(torch.nn.Sequential(
            RSU6(64,16,64),  # 6层RSU
        ))
        self.down3 = Down(torch.nn.Sequential(
            RSU5(64,16,64),  # 5层RSU
        ))
        self.down4 = Down(torch.nn.Sequential(
            RSU4(64,16,64),  # 4层RSU
        ))
        self.down5 = Down(torch.nn.Sequential(
            RSU4F(64,16,64),  # 4层RSU全卷积版本
        ))

        # 解码器部分（5级上采样）
        self.up1 = Up(torch.nn.Sequential(RSU4F(64,16,64)))
        self.up2 = Up(torch.nn.Sequential(RSU4(64,16,64)))
        self.up3 = Up(torch.nn.Sequential(RSU5(64,16,64)))
        self.up4 = Up(torch.nn.Sequential(RSU6(64,16,64)))
        self.up5 = Up(torch.nn.Sequential(RSU7(64,16,64)))

        # 多尺度特征融合模块（不同上采样比例）
        self.fuse5 = Fuse(ConvRelu(64 + 64, 64), scale=16)
        self.fuse4 = Fuse(ConvRelu(64 + 64, 64), scale=8)
        self.fuse3 = Fuse(ConvRelu(64 + 64, 64), scale=4)
        self.fuse2 = Fuse(ConvRelu(64 + 64, 64), scale=2)
        self.fuse1 = Fuse(ConvRelu(64 + 64, 64), scale=1)

        # 条带池化模块（增强长条形裂缝特征提取）
        self.spooling = StripPooling(64)
        self.spooling1 = StripPooling(64)
        self.spooling2 = StripPooling(64)
        self.spooling3 = StripPooling(64)
        self.spooling4 = StripPooling(64)
        self.spooling5 = StripPooling(64)

        # 最终融合层（将5级预测结果融合）
        self.final = Conv3X3(5, 1)

    def forward(self,inputs):
        # 编码器前向传播
        out, down1= self.down1(inputs)
        out, down2= self.down2(out)
        out, down3= self.down3(out)
        out, down4= self.down4(out)
        out, down5= self.down5(out)
        out = self.spooling(out)  # 底部特征条带池化

        # 解码器前向传播
        up5 = self.up5(out, down5)
        up4 = self.up4(up5, down4)
        up3 = self.up3(up4, down3)
        up2 = self.up2(up3, down2)
        up1 = self.up1(up2, down1)

        # 多尺度特征融合（每级都应用条带池化）
        fuse5 = self.fuse5(down_inp=self.spooling5(down5),up_inp=up5)
        fuse4 = self.fuse4(down_inp=self.spooling4(down4), up_inp=up4)
        fuse3 = self.fuse3(down_inp=self.spooling3(down3), up_inp=up3)
        fuse2 = self.fuse2(down_inp=self.spooling2(down2), up_inp=up2)
        fuse1 = self.fuse1(down_inp=self.spooling1(down1), up_inp=up1)

        # 最终输出（拼接5级预测结果）
        output = self.final(torch.cat([fuse5,fuse4,fuse3,fuse2,fuse1],1))

        return output, fuse5, fuse4, fuse3, fuse2, fuse1  # 返回最终输出和各级特征


if __name__ == '__main__':
    # 生成测试用随机张量：模拟1张512x512分辨率的RGB图像输入
    inp = torch.randn((1, 3, 512, 512))  # [batch, channel, height, width]

    # 实例化DeepCrack模型
    model = DeepCrack_uu_Sp_3()  # 初始化网络结构

    # 计算模型参数量（重要性能指标）
    para = sum([np.prod(list(p.size())) for p in model.parameters()])  # 遍历所有参数计算总数量
    # 格式化输出参数量（转换为MB单位，假设32位浮点数占4字节）
    print('Model {} : params: {:4f}M'.format(model._get_name(), para * 4 / 1000 / 1000))

    # 注释掉的调试代码（原用途可能是）：
    # DNN_printer(model,())   # 可视化网络结构（需第三方库支持）
    # out_big = model(inp)        # 执行前向传播验证计算流程
